package es.geoorge.hundirlaflota;

/**
 * La clase encargada del control de los barcos creados y sus atributos.
 * @author Georthik
 * @version x.x
 */

public class Barco {
    private int x,y,ancho,longitud,numBarco,casillax,casillay;
    private boolean orientacion=true;//si es true sera horizontal
    private int[][] matriz= new int[10][10];
    private int vecesTocado=0;

    /**
     * Constructor de la clase, se usara para dibujar el barco que se utilizara para la colocacion de los barcos al crear el tablero, en el panel inferior.
     * @param x la coordenada izquierda de la que se parte para dibujarlo en el onDraw(), medido en pixeles.
     * @param y la coordenada superior de la que se parte para dibujarlo en el onDraw(), medido en pixeles.
     * @param ancho el ancho de los cuadrados del tablero , medido en pixeles.
     * @param longitud el largo del barco, multiplicado por el ancho y sumado a la coordenada x nos daria la coordenada derecha del barco dibujado. Medido en {@link Casilla}s
     */
    public Barco(int x,int y, int ancho,int longitud) {
        this.x=x;
        this.y=y;
        this.ancho=ancho;
        this.longitud=longitud;
    }
    
    /**
     * Constructor de la clase, se usara para dibujar el barco que ya se ha colocado, sera permanente en el panel del jugador.
     * @param casillax la coordenada x de la casilla en la que empieza el barco.
     * @param casillay la coordenada y de la casilla en la que empieza el barco.
     * @param x la coordenada izquierda de la que se parte para dibujarlo en el onDraw, medido en pixeles.
     * @param y la coordenada superior de la que se parte para dibujarlo en el onDraw, medido en pixeles.
     * @param orientacion indica si la orientacion del barco es horizontal o vertical.
     * @param longitud el largo del barco, multiplicado por el ancho y sumado a la coordenada x nos daria la coordenada derecha del barco dibujado. Medido en {@link Casilla}s
     * @param matriz la matriz numerica con la que trabaja la logica del juego para calcular las posiciones de los barcos.
     * @param numBarco es el valor UNICO y DISTINTO para cada barco que se insertara en la matriz numerica para reconocer los barcos.
     */
    public Barco(int casillax, int casillay,int x,int y, boolean orientacion,int longitud,int matriz[][],int numBarco) {
        this.casillax=casillax;
        this.casillay=casillay;
        this.x=x;
        this.y=y;
        this.orientacion=orientacion;
        this.longitud=longitud;
        this.matriz=matriz;
        this.numBarco=numBarco;
    }
    
    /**
     * Constructor de la clase, se usara para dibujar el barco que se esta moviendo, sirve tambien como comprobacion para evitar que salgan del tablero o se superpongan
     * @param pcasillax la coordenada x de la casilla en la que empieza el barco.
     * @param pcasillay la coordenada y de la casilla en la que empieza el barco.
     * @param porientacion indica si la orientacion del barco es horizontal o vertical.
     * @param plongitud el largo del barco, multiplicado por el ancho y sumado a la coordenada x nos daria la coordenada derecha del barco dibujado. Medido en {@link Casilla}s
     * @param pmatriz la matriz numerica con la que trabaja la logica del juego para calcular las posiciones de los barcos.
     * @param pnumBarco es el valor UNICO y DISTINTO para cada barco que se insertara en la matriz numerica para reconocer los barcos.
     * @exception ArrayIndexOutBoundsException cuando el barco sale del tablero, la matriz numerica, o se superpone a otro barco se fuerza el error para tratarlo y corregirlo en la clase principal.
     */
    public Barco(int pcasillax, int pcasillay, boolean porientacion, int plongitud,int pmatriz[][],int pnumBarco){
        casillax=pcasillax;
        casillay=pcasillay;
        orientacion=porientacion;
        longitud=plongitud;
        matriz=pmatriz;
        numBarco=pnumBarco;
        if(!orientacion){
            for(int i=0;i<longitud;i++){
                if(matriz[casillax+i][casillay]==0){
                    matriz[casillax+i][casillay]=numBarco;                                  
                }else{
                    if(numBarco==0&&matriz[casillax+i][casillay]!=9){
                        matriz[casillax+i][casillay]=numBarco;
                    }else{
                        matriz[11][11]=0;
                    }
                }
            }
        }else{
            for(int i=0;i<longitud;i++){
                if(matriz[casillax][casillay+i]==0){
                    matriz[casillax][casillay+i]=numBarco;                                  
                }else{
                    if(numBarco==0&&matriz[casillax][casillay+i]!=9){
                        matriz[casillax][casillay+i]=numBarco;
                    }else{
                        matriz[11][11]=0;
                    }
                }
            }
        }
        if(numBarco!=0){
            ponAgua();
        }
    }
    
    /**
     * Metodo que se usa para colocar una "capa" de agua fija alrededor del barco para obligar a que los barcos esten serparados por un minimo de una casilla de agua por todos sus extremos.
     * @return null
     */
	//Las excepciones aqui provocadas no se tratan porque solo puede fallar por llegar al fin de la cuadricula en cuyo caso no es necesario poner agua, obviamente porque nunca se podra poner un barco fuera de la matriz
    public void ponAgua(){
    	if(!orientacion){
            for(int i=casillax-1;i<=casillax+longitud;i++){
                for(int j=casillay-1;j<=casillay+1;j++){
                    try{
	                    if(matriz[i][j]==0||matriz[i][j]==9){                           
	                    	matriz[i][j]=9;
	                    }
                    }catch(Exception e){}
                }
            }
        }else{
            for(int i=casillax-1;i<=casillax+1;i++){
                for(int j=casillay-1;j<=casillay+longitud;j++){
                    try{
                        if(matriz[i][j]==0||matriz[i][j]==9){                           
                            matriz[i][j]=9;
                        }
                    }catch(Exception e){}
                }
            }
        }
    }
    
    /**
     * Este metodo se encarga de comprobar si las coordenadas recibidas se enucentran dentro de la superficie del barco.
     * @param xx la coordenada x del punto a comprobar, medido en pixeles.
     * @param yy la coordenada y del punto a comprobar, medido en pixeles.
     * @return boolean con valor true si se cumple que el punto forme parte de la superficie y false si no es asi.
     */
    public boolean dentro(int xx,int yy) {
        if(orientacion){
            if (xx>=this.x && xx<=(this.x+ancho*longitud) && yy>=this.y && yy<=this.y+ancho) 
                    return true;
            else
                return false;
        }else{
            if (xx>=this.x && xx<=this.x+ancho && yy>=this.y && yy<=(this.y+ancho*longitud)) 
                    return true;
            else
                return false;
        }
    }
    
    /**
     * 
     * @return orientacion del barco
     */
    public boolean getOrientacion(){
        return orientacion;
    }
    
    /**
     * Sirve para indicar la orientacion del barco.
     * @param p indica la orientacion del barco, true si es horizontal y false en caso de que sea vertical.
     */
    public void setOrientacion(boolean p){
        orientacion=p;
    }

    /**
     * 
     * @return longitud del barco
     */
    public int getLongitud(){
        return longitud;
    }
    
    /**
     * Nos permite indicar o modificar la longitud del barco
     * @param longitud
     */
    public void setLongitud(int longitud){
        this.longitud=longitud;
    }
    
    /**
     * Nos permite indicar o modificar el ancho (se usara en multijugador), medido en pixeles.
     * @param p ancho de la casilla de la cuadricula
     */
    public void setAncho(int p){
        ancho=p;
    }

    /**
     * Devuelve la coordenada x del barco para dibujarlo en el onDraw(), medido en pixeles.
     * @return x 
     */
    public int getX(){
        return x;
    }
    
    /**
     * Devuelve la coordenada y del barco para dibujarlo en el onDraw(), medido en pixeles.
     * @return y 
     */
    public int getY(){
        return y;
    }

    /**
     * Devuelve un booleano que indica si este barco ya ha sido hundido o le faltan casillas por descubrir.
     * @return boolean a true si esta hundido, false si no es asi.
     */
    public boolean estaHundido(){
        if(vecesTocado>=longitud){
        return true;
        }
        return false;
    }
    
    /**
     * incrementa el numero de las veces que ha sido tocado el barco para calcular cuando esta hundido.
     */
    public void tocado(){
        vecesTocado++;
    }
    
    /**
     * Metodo encargado de comprobar si las coordenadas indicadas de la matriz contienen agua o parte del barco.
     * En caso de que se encuentre el barco llama al metodo tocado()
     * @param x coordenada x de la casilla a comprobar en la matriz
     * @param y coordenada y de la casilla a comprobar en la matriz
     * @return true cuando se toca un barco false cuando es agua.
     */
    public boolean comprobarCoor(int x,int y){
        try{
            if(matriz[x][y]!=0 && matriz[x][y]!=9){
                matriz[x][y]=0;
                tocado();
                return true;
            }
        }catch(Exception e){}
        return false;
    }       
    
    /**
     * Devuelve el numero identificador del barco.
     * @return numBarco
     */
    public int getNumBarco(){
    	return numBarco;
    }

}